// Copyright (C) 2010  Joan Puigcerver Perez, <joapuipe@gmail.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//

#ifndef __TCPCLIENTSESSION_HPP__
#define __TCPCLIENTSESSION_HPP__

#include <iostream>
#include <cc++/socket.h>

#include <Database.hpp>
#include <XMLUtils.hpp>
#include <LogUtils.hpp>

/**
 * \class TCPClientSession
 *
 * Class used to manage the input connections.
 *
 * Each object run as a independent thread. It waits for a request
 * from the connected user, computes the response and sends it to
 * the user.
 */
class TCPClientSession: public ost::TCPSession {
private:
  static const size_t max_request_size;

  const Database * database;
  const std::string client_ip;
  std::ostream& logfile;
  ost::Mutex& log_mutex;

  char * request; 
  size_t req_size;
  std::stringstream response;

  void run(void);
  void final(void);
  
  int get_request(void);
  int process_request(void);
  int send_response(void);
  
  void build_header_response(void);
  void build_end_response(void);
  void build_error_response(const unsigned int code, const std::string& message);
  void build_explain_response(const std::string& name, const Database::TPersonSearch& lst);
  void build_distance_response(const std::string& source, const std::string& target, const Filter& filter);
  void build_distanceN_response(const std::string& source, const uint32_t hops, const Filter& filter);
  void build_center_response(const std::string& source, const Filter& filter);
  
  void print_log_request(const std::string& request);
  void print_log_response(const std::string& response);
  
public:
  /**
   * Constructor.
   * @param db Database object.
   * @param server TCPSocket which manages the input connections.
   * @param timeout Connection timeout.
   * @param logfile Output stream used to print log messages.
   * @param log_mutex Mutex used to assure that no two lines are printed to
   *                  logfile at the same time.
   */
  TCPClientSession(const Database * db, ost::TCPSocket &server, 
		   timeout_t timeout = TIMEOUT_INF, 
		   std::ostream& logfile = std::cout, 
		   ost::Mutex& log_mutex = LOGmutex);

  /** Destructor. */
  ~TCPClientSession();
};

#endif
